<chapter xml:id="type_traits.h">
<title><tt>__vic/type_traits.h</tt></title>

<p>Template metaprogramming support.</p>
<p>All the predicate metafunctions have boolean member <tt>value</tt> and,
usually, derived from <tt>integral_constant</tt>.</p>
<p>All the type transformer metafunctions have type member <tt>type</tt>
containing the conversion result.</p>
<p>All of the template aliases are available only in C++11 mode.</p>


<chapter xml:id="integral_constant">
<title><tt>integral_constant</tt></title>

<code-block lang="C++"><![CDATA[
template<class T, T Val>
struct integral_constant
{
    using value_type = T;
    using type = integral_constant<T, Val>;

    static constexpr T value = Val;
};
]]></code-block>

<p>The topmost base class of the most metafunctions.</p>

</chapter>


<chapter xml:id="true_type">
<title><tt>true_type</tt></title>

<code-block lang="C++"><![CDATA[
using true_type = integral_constant<bool, true>;
]]></code-block>

<p>Base class for predicate metafunctions that have value <tt>true</tt>.</p>

</chapter>


<chapter xml:id="false_type">
<title><tt>false_type</tt></title>

<code-block lang="C++"><![CDATA[
using false_type = integral_constant<bool, false>;
]]></code-block>

<p>Base class for predicate metafunctions that have value <tt>false</tt>.</p>

</chapter>


<chapter xml:id="is_same">
<title><tt>is_same</tt></title>

<code-block lang="C++"><![CDATA[
template<class T1, class T2> struct is_same;
]]></code-block>

<p>A predicate. True if <tt>T1</tt> and <tt>T2</tt> are exactly the same
type.</p>

</chapter>


<chapter xml:id="is_const">
<title><tt>is_const</tt></title>

<code-block lang="C++"><![CDATA[
template<class T> struct is_const;
]]></code-block>

<p>A predicate. True if <tt>T</tt> has <tt>const</tt> qualifier.</p>

</chapter>


<chapter xml:id="is_byte">
<title><tt>is_byte</tt></title>

<code-block lang="C++"><![CDATA[
template<class T> struct is_byte;
]]></code-block>

<p>A predicate. True, if <tt>T</tt> is a type representing byte:</p>
<list style="bulleted">
    <item><tt>char</tt></item>
    <item><tt>unsigned char</tt></item>
    <item><tt>std::byte</tt> <badge>C++17</badge></item>
    <item><tt>char8_t</tt> <badge>C++20</badge></item>
</list>

</chapter>


<chapter xml:id="byte_cast">
<title><tt>byte_cast()</tt></title>

<code-block lang="C++"><![CDATA[
template<class To, class From>
constexpr To byte_cast(From v);
]]></code-block>

<p>Casts value of <tt>From</tt> type to <tt>To</tt> type if both types are
byte types (see <xref to="is_byte"/>).</p>

<precondition>is_byte&lt;From>::value &amp;&amp; is_byte&lt;To>::value</precondition>

</chapter>


<chapter xml:id="is_signed_integer">
<title><tt>is_signed_integer</tt></title>

<code-block lang="C++"><![CDATA[
template<class T> struct is_signed_integer;
]]></code-block>

<p>A predicate. True if <tt>T</tt> is a one of the "standard signed integer
types" (see the Standard).</p>

</chapter>


<chapter xml:id="is_unsigned_integer">
<title><tt>is_unsigned_integer</tt></title>

<code-block lang="C++"><![CDATA[
template<class T> struct is_unsigned_integer;
]]></code-block>

<p>A predicate. True if <tt>T</tt> is a one of the "standard unsigned integer
types" (see the Standard).</p>

</chapter>


<chapter xml:id="conjunction">
<title><tt>conjunction</tt> <badge>C++11</badge></title>

<code-block lang="C++"><![CDATA[
template<class... B> struct conjunction;
]]></code-block>

<p>A predicate. The logical conjunction of the predicates <tt>B...</tt>.
False iff one of the <tt>B...</tt> is false.</p>

</chapter>


<chapter xml:id="disjunction">
<title><tt>disjunction</tt> <badge>C++11</badge></title>

<code-block lang="C++"><![CDATA[
template<class... B> struct disjunction;
]]></code-block>

<p>A predicate. The logical disjunction of the predicates <tt>B...</tt>.
True iff one of the <tt>B...</tt> is true.</p>

</chapter>


<chapter xml:id="negation">
<title><tt>negation</tt></title>

<code-block lang="C++"><![CDATA[
template<class B> struct negation;
]]></code-block>

<p>A predicate. The logical negation of the predicate <tt>B</tt>.</p>

</chapter>


<chapter xml:id="remove_const">
<title><tt>remove_const</tt></title>

<code-block lang="C++"><![CDATA[
template<class T> struct remove_const;
template<class T> using remove_const_t = typename remove_const<T>::type;
]]></code-block>

<p>A type transformer. Removes the top-level <tt>const</tt> qualifier or just
returns <tt>T</tt> if it doesn't have such qualifier.</p>

</chapter>


<chapter xml:id="remove_volatile">
<title><tt>remove_volatile</tt></title>

<code-block lang="C++"><![CDATA[
template<class T> struct remove_volatile;
template<class T> using remove_volatile_t = typename remove_volatile<T>::type;
]]></code-block>

<p>A type transformer. Removes the top-level <tt>volatile</tt> qualifier or just
returns <tt>T</tt> if it doesn't have such qualifier.</p>

</chapter>


<chapter xml:id="remove_cv">
<title><tt>remove_cv</tt></title>

<code-block lang="C++"><![CDATA[
template<class T> struct remove_cv;
template<class T> using remove_cv_t = typename remove_cv<T>::type;
]]></code-block>

<p>A type transformer. Removes any top-level cv-qualifier or just returns
<tt>T</tt> if it doesn't have such qualifiers.</p>

</chapter>


<chapter xml:id="remove_reference">
<title><tt>remove_reference</tt></title>

<code-block lang="C++"><![CDATA[
template<class T> struct remove_reference;
template<class T> using remove_reference_t = typename remove_reference<T>::type;
]]></code-block>

<p>A type transformer. Returns the type referred by <tt>T</tt> or just
<tt>T</tt> if it isn't a reference type.</p>

</chapter>


<chapter xml:id="remove_cvref">
<title><tt>remove_cvref</tt></title>

<code-block lang="C++"><![CDATA[
template<class T> struct remove_cvref;
template<class T> using remove_cvref_t = typename remove_cvref<T>::type;
]]></code-block>

<p>A type transformer. Applies <tt>remove_reference</tt> then <tt>remove_cv</tt>
to <tt>T</tt>.</p>

</chapter>


<chapter xml:id="remove_pointer">
<title><tt>remove_pointer</tt></title>

<code-block lang="C++"><![CDATA[
template<class T> struct remove_pointer;
template<class T> using remove_pointer_t = typename remove_pointer<T>::type;
]]></code-block>

<p>A type transformer. Returns the type pointed by <tt>T</tt> or just
<tt>T</tt> if it isn't a pointer type.</p>

</chapter>


<chapter xml:id="conditional">
<title><tt>conditional</tt></title>

<code-block lang="C++"><![CDATA[
template<bool Cond, class Then, class Else> struct conditional;

template<bool Cond, class Then, class Else>
using conditional_t = typename conditional<Cond, Then, Else>;
]]></code-block>

<p>A type transformer. Returns <tt>Then</tt> if <tt>Cond == true</tt>.
<tt>Else</tt> is returned otherwise.</p>

</chapter>


<chapter xml:id="enable_if">
<title><tt>enable_if</tt>, <tt>disable_if</tt></title>

<code-block lang="C++"><![CDATA[
template<bool Test, class T = void>
struct enable_if
{
    using type = T;
};
template<class T>
struct enable_if<false, T> {};

template<bool Test, class T = void>
struct disable_if : enable_if<!Test, T> {};
]]></code-block>

<p>Classical tools for SFINAE-magic.</p>

</chapter>


<chapter xml:id="index_sequence">
<title><tt>index_sequence</tt>, <tt>make_index_sequence</tt> <badge>C++11</badge></title>

<code-block lang="C++"><![CDATA[
template<size_t... I>
struct index_sequence
{
    static constexpr size_t size() { return sizeof...(I); }
};

template<size_t Size>
using make_index_sequence = index_sequence<0, 1, ..., Size-1>;
]]></code-block>

<p>Implementation of C++14 <tt>std::index_sequence</tt> for C++11.</p>

<note>Unlike <tt>std::index_sequence</tt> it isn't a special case of some sort
of <tt>std::integer_sequence</tt>.</note>

</chapter>


</chapter>
